package com.danielschon.triangularity.sprites;

import org.andengine.entity.sprite.Sprite;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.util.color.Color;

import com.danielschon.triangularity.activities.MainActivity;
import com.danielschon.triangularity.sprites.Bullet.OnTimeoutListener;
import com.danielschon.triangularity.utility.Tail;
import com.danielschon.triangularity.utility.Util;
import com.danielschon.triangularity.utility.Vec;

public class Ship extends Sprite{

	/**
	 * The 'main character', so to speak
	 */
	
	//=======================
	//Constants
	//=======================
	
	public static final float MAX_SPEED = 2;
	public static final float ACCELERATION = 0.5f;
	public static final float DECELERATION = 1f;
	public static final float FRICTION = .05f;
	public static final float FIRING_POWER = 20;
	
	
	//=======================
	//Fields
	//=======================
	
	public float direction = 0;		//in radians
	public Vec location;
	public Vec movement;
	public float velocity;
	
	public MainActivity activity;
	Tail tail;
	
	boolean isWrap = false;			//used to remember whether a movement wrapped the screen
	
	//=======================
	//Constructor
	//=======================
	
	public Ship(float pWidth, float pHeight,
			ITextureRegion pTextureRegion,
			VertexBufferObjectManager vertexBufferObjectManager, MainActivity a) {
		super(pWidth, pHeight, pTextureRegion, vertexBufferObjectManager);
		
		activity = a;
		this.setRotationCenter(this.getWidth()/2, this.getHeight()/2);
		location = new Vec(this.getX(), this.getY());
		movement = new Vec(0,0);
		
		/* make the tail */
		tail = new Tail(16, 32, this);
		tail.addColor(new Color(Color.BLACK));
		tail.addColor(new Color(Color.YELLOW));
	}
	
	//=======================
	//Methods
	//=======================
	
	public void setDirection(float dir){
		direction = dir;
		this.setRotation(Util.radToDeg(dir));
	}
	
	/*
	 * What happens every tick
	 */
	
	@Override
	public void onManagedUpdate(float pSecondsElapsed){
		
		/* update tail */
		if (tail != null){
			tail.check(isWrap);
		}
		
		/* Accelerate */
		if (activity.sprAccel.isPressed()){
			Vec force = Util.radToVec(direction);
			force.mult(ACCELERATION);
			movement.add(force); 
		}
		
		/* Decelerate */
		Vec force = Util.radToVec(Util.vecToRad(movement));
		float decel;
		if (activity.sprBrake.isPressed()){
			decel = DECELERATION;
		}else{
			decel = FRICTION;
		}
		force.mult(-decel);
		movement.add(force); 
		if (Util.vecSpeed(movement) <= decel){
			movement.set(0, 0);
		}
		
		/* set the new location */
		location.add(movement);

		/* Check for screen wrap and wrap if necessary */
		if (location.x > MainActivity.CAMERA_WIDTH){
			location.x = 0;
			isWrap = true;
		}
		if (location.x < 0){
			location.x = MainActivity.CAMERA_WIDTH;
			isWrap = true;
		}
		if (location.y > MainActivity.CAMERA_HEIGHT){
			location.y = 0;
			isWrap = true;
		}
		if (location.y < 0){
			location.y = MainActivity.CAMERA_HEIGHT;
			isWrap = true;
		}
		this.setPosition(location.x, location.y);
		
	}
	
	public Bullet shoot(){
		Vec p = Util.radToVec(direction);
		p.mult(FIRING_POWER);
		p.add(movement);
		final Bullet bullet = new Bullet(this.getX() + this.getWidth()/2, this.getY() + this.getHeight()/2, activity.texBullet,  getVertexBufferObjectManager(), p, this);
		bullet.setOnTimeoutListener(new OnTimeoutListener(){
			public void onTimeout(Bullet b) {
				activity.destroyEntity(b);
			}
		});
		activity.scene.attachChild(bullet);
		return bullet;
	}
	
	/*
	 * Overrides setPosition to center the ship
	 */
	
	@Override
	public void setPosition(float pX, float pY){
		super.setPosition(pX - this.getWidth()/2, pY - this.getHeight()/2);
	}
	
	public void resetTail(){
		tail.reset();
	}
	
	public void resetIsWrap() {
		isWrap = false;
	}
	
}
